"""
2.	近年来，汽车车牌检测已经越来越受到人们的重视，特别是在智能交通系统中，汽车牌照检测发挥了巨大的作用。
根据OpenCV相关技术，依据以下要求步骤，完成给定图像的车牌检测（参照下图）（30分）

https://blog.csdn.net/weixin_41695564/article/details/79712393

OpenCV实战（一）——简单的车牌识别
"""

import cv2 as cv
import numpy as np
import sys
from python_ai.common.xcommon import *

np.random.seed(1)
title_no = 0

# ①	读取图像文件，打印图片维度和尺度
# path = 'image/car.png'
path = '../../../../large_data/CV3/exam/weekly02/car.png'
img = cv.imread(path, cv.IMREAD_COLOR)
H, W, CH = img.shape
print('打印图片维度和尺度:', img.shape)
title_no += 1
cv.imshow(f'{title_no} img', img)

# ②	图像降噪处理
# ③	形态学处理
# ④	阈值分割
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
title_no += 1
cv.imshow(f'{title_no} gray', gray)

blur = cv.GaussianBlur(gray, (5, 5), 0, None, 0, cv.BORDER_DEFAULT)
print_numpy_ndarray_info(blur, 'blur')
title_no += 1
cv.imshow(f'{title_no} blur', blur)

kernel = np.ones([23, 23], np.uint8)
opening = cv.morphologyEx(blur, cv.MORPH_OPEN, kernel)
title_no += 1
cv.imshow(f'{title_no} opening', opening)

opening = cv.addWeighted(gray, 1, opening, -1, 0)
title_no += 1
cv.imshow(f'{title_no} weighted added', opening)

ret, otsu = cv.threshold(opening, 0, 255, cv.THRESH_OTSU + cv.THRESH_BINARY)
title_no += 1
cv.imshow(f'{title_no} otsu', otsu)

canny = cv.Canny(otsu, 100, 200)
title_no += 1
cv.imshow(f'{title_no} canny', canny)

kernel = np.ones([10, 10], np.uint8)
canny = cv.morphologyEx(canny, cv.MORPH_CLOSE, kernel)
title_no += 1
cv.imshow(f'{title_no} canny close', canny)
canny = cv.morphologyEx(canny, cv.MORPH_OPEN, kernel)
title_no += 1
cv.imshow(f'{title_no} canny close open', canny)

# ⑤	边缘检测
contours, hierarchy = cv.findContours(canny, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
print('contours: ', len(contours))


def drawContours(contours):
    global title_no
    bg = np.zeros_like(img, dtype=np.uint8)
    for c in contours:
        cv.drawContours(bg, [c], 0, (
            np.random.randint(0, 256),
            np.random.randint(0, 256),
            np.random.randint(0, 256),
        ), 1)
    title_no += 1
    cv.imshow(f'{title_no} contours', bg)


drawContours(contours)

# ⑥	筛选车牌轮廓，用绿色线条框出来
selected_contours = []
selected_contours_areas = []
for c in contours:
    x, y, w, h = cv.boundingRect(c)
    area = w * h
    if 2 < w / h < 5.5:
        selected_contours.append(c)
        selected_contours_areas.append(area)

idx_of_max = np.argsort(selected_contours_areas)[::-1][0]
car_plate_contour = selected_contours[idx_of_max]
drawContours([car_plate_contour])

print(np.shape(car_plate_contour))
col_min, row_min = np.min(car_plate_contour[:, 0, :], axis=0)
col_max, row_max = np.max(car_plate_contour[:, 0, :], axis=0)
roi = img[row_min:row_max, col_min:col_max]
img_bg = img.copy()
cv.rectangle(img_bg, (col_min, row_min), (col_max, row_max), (0, 255, 0), 1)
title_no += 1
cv.imshow(f'{title_no} tick', img_bg)
title_no += 1
cv.imshow(f'{title_no} roi', roi)

# finally
print('Press any key on image window to exit ...')
cv.waitKey(0)
cv.destroyAllWindows()
sys.exit(0)
